#include "script_utility.h"
#include "MonoBehaviour.h"
#include "mono_script.h"
#include "script_general_manager.h"



static const MethodParam MonoBehaviourMethod[MonoBehaviour::MaxFixedMethod] = 
{
	{"Reset",0},
	{"Start",0},
	{"Update",0},
	{"Awake",0},
	{"FixedUpdate",0}
};

__ImplementClass(MonoBehaviour,std::string("MonoBehaviour"), Component);

MonoBehaviour::MonoBehaviour()
{
	m_bScript = true;
    mFixedFrame = 0;
	mCurFrame = 0;
	memset(mFixedMethod,0,MaxFixedMethod*sizeof(int));

}

MonoBehaviour::~MonoBehaviour()
{

}

void MonoBehaviour::Init(const char* className)
{
	setName(std::string(className));
	MonoClass* mono_class = App::ScriptGeneralManager::Instance()->GetMonoClassByName(className, "UnityEngine", App::s_cpScriptEngineLibrary);

	for (int i = 0; i < MaxFixedMethod; ++i)
	{
		mFixedMethod[i] = mono_class_get_method_from_name( 
			mono_class, 
			MonoBehaviourMethod[i].Name, 
			MonoBehaviourMethod[i].ParamCount );
		
	}
}

void MonoBehaviour::Invoke(int index)
{

}

void MonoBehaviour::Invoke(const char* methodName)
{


	App::TMonoScriptPtr TMonoScript = App::ScriptGeneralManager::Instance()->GetMonoScript( getName(), "UnityEngine", "UnityEngine.dll", true);
	if (!TMonoScript.isNull())
	{
		MonoMethod *pMethod = TMonoScript->GetMethodByName(methodName);
		
		if(pMethod)
		{
		   void* params[1] = {0};
		   MonoObject* exc = NULL;
		   MonoObject* ret = NULL;
		   ret = mono_runtime_invoke( pMethod, mMonoObj, params , &exc );
		   if ( exc!=NULL )
		   {
			   String error = App::Utility_ExceptionToString( exc );
		   }
			
		}
	}

   
}

void MonoBehaviour::Start()
{
	if (mFixedMethod[MethodStart])
	{
		void* params[1] = {0};
		MonoObject* exc = NULL;
		MonoObject* ret = NULL;
		ret = mono_runtime_invoke( mFixedMethod[MethodStart], mMonoObj, params , &exc );
		if ( exc!=NULL )
		{
			String error = App::Utility_ExceptionToString( exc );

		}
	}
}

void MonoBehaviour::Reset()
{
	if (mFixedMethod[MethodReset])
	{
		void* params[1] = {0};
		MonoObject* exc = NULL;
		MonoObject* ret = NULL;
		ret = mono_runtime_invoke( mFixedMethod[MethodReset], mMonoObj, params , &exc );
		if ( exc!=NULL )
		{
			String error = App::Utility_ExceptionToString( exc );

		}
	}
}

void MonoBehaviour::Awake()
{
	if (mFixedMethod[MethodAwake])
	{
		void* params[1] = {0};
		MonoObject* exc = NULL;
		MonoObject* ret = NULL;
		ret = mono_runtime_invoke( mFixedMethod[MethodAwake], mMonoObj, params , &exc );
		if ( exc!=NULL )
		{
			String error = App::Utility_ExceptionToString( exc );

		}
	}
}

void MonoBehaviour::Update(float delta)
{    

	 if(mFixedFrame == 0)
	 {
		 if (mFixedMethod[MethodUpdate])
		 {
			 void* params[1] = {0};
			 MonoObject* exc = NULL;
			 MonoObject* ret = NULL;
			 ret = mono_runtime_invoke( mFixedMethod[MethodUpdate], mMonoObj, params , &exc );
			 if ( exc!=NULL )
			 {
				 String error = App::Utility_ExceptionToString( exc );

			 }
		 }
	 }
	 else
	 {
		 mCurFrame++;
		 if (mCurFrame >= mFixedFrame)
		 {
			 if (mFixedMethod[MethodFixedUpdate])
			 {
				 void* params[1] = {0};
				 MonoObject* exc = NULL;
				 MonoObject* ret = NULL;
				 ret = mono_runtime_invoke( mFixedMethod[MethodFixedUpdate], mMonoObj, params , &exc );
				 if ( exc!=NULL )
				 {
					 String error = App::Utility_ExceptionToString( exc );

				 }
			 }
			 mCurFrame = 0;
		 }
	 }
    
}